package UI

import "fmt"

/*
已被支持的事件
	OnMove: 节点位移
	OnSizeChange: 节点大小更改
	OnShow: 节点从隐藏中显示
	OnHidden: 节点从显示中隐藏
	OnInput: 文本数据更改
	OnRemove: 节点被删除
	OnSelect: 节点被选中，被选中的节点可以使用OnKeyBord事件监听按键事件，如果节点没有对应的处理函数那么选中将会失效
	OnKeyBord: 节点被按中且键盘被按下时触发
*/

// createEvent 添加事件
// @parma node: 要创建事件的node
// @return 执行结果
func createEvent(node Node) bool {
	attr, _ := node.GetAttr()
	_, ok := eventStore.Load(attr.Key)
	if !ok {
		eventStore.Store(attr.Key, Event{})
	}

	return !ok
}

// deleteEvent 删除事件
// @parma 要删除事件的node
// @return 执行结果
func deleteEvent(node Node) bool {
	attr, _ := node.GetAttr()
	_, ok := eventStore.Load(attr.Key)
	if ok {
		eventStore.Delete(attr.Key)
	}
	return ok
}

// addEvent 添加事件
// @parma node: 要添加事件的node  eventName: 事件类型  callback: 事件回调
// @return 执行结果
func addEvent(node Node, eventName uint8, callback EventCallBack) bool {
	if callback == nil {
		return false
	}
	attr, _ := node.GetAttr()
	nodeEventAny, ok := eventStore.Load(attr.Key)

	nodeEvent := nodeEventAny.(Event)

	if ok {
		callbackStack, ok := nodeEvent[eventName]
		if ok {
			nodeEvent[eventName] = append(callbackStack, callback)
		} else {
			nodeEvent[eventName] = []EventCallBack{callback}
		}
		return true
	}

	return false

}

// untieEvent 解绑事件
// @parma node: 要解绑事件的node  eventName: 事件类型  callback: 事件回调
// @return 执行结果
func untieEvent(node Node, eventName uint8, callback EventCallBack) bool {
	if callback == nil {
		return false
	}
	attr, _ := node.GetAttr()
	nodeEventAny, ok := eventStore.Load(attr.Key)
	nodeEvent := nodeEventAny.(Event)
	callbackKey := fmt.Sprintf("%v", callback)
	if ok {
		callbackStack, ok := nodeEvent[eventName]
		if ok {
			for index, nodeCB := range callbackStack {
				if callbackKey == fmt.Sprintf("%v", nodeCB) {
					nodeEvent[eventName] = append(callbackStack[:index], callbackStack[index+1:]...)
				}
			}

			if len(nodeEvent[eventName]) == 0 {
				delete(nodeEvent, eventName)
			}

		}
	}
	return false
}

// triggerEvent 触发事件
// @parma node: 要解绑事件的node  eventName: 事件类型  origen: 事件源node
// @return 执行结果
func triggerEvent(node Node, eventName uint8, origen Node) bool {
	attr, _ := node.GetAttr()
	nodeEventAny, ok := eventStore.Load(attr.Key)

	nodeEvent := nodeEventAny.(Event)

	if ok {
		callbackStack, ok := nodeEvent[eventName]
		if ok {
			for _, callBack := range callbackStack {
				if callBack != nil {
					callBack(node, origen)
				}
			}
		}
		return ok
	}
	return false
}

// displayEventTrigger 节点Display事件通知
// @parma node: 目标节点  origen: 事件源node  display: 事件类型  deep: 是否进行深度通知
func displayEventTrigger(node Node, origen Node, display bool, deep bool) {
	key := OnShow
	if display == false {
		key = OnHidden
	}

	style, _ := node.GetStyle()

	if style.Display != false { //只有node可显的时候触发事件
		triggerEvent(node, key, origen)

		if deep {
			childNodes, _ := node.GetChildren()
			for _, childNode := range childNodes {
				displayEventTrigger(childNode, origen, display, deep)
			}
		}
	}

}

// autoSizeChangeTrigger 处理带有自适应属性的Node
// @parma node: 目标节点  origen: 事件源node  deep: 是否进行深度通知
func autoSizeChangeTrigger(node Node, origen Node, deep bool) {
	style, _ := node.GetStyle()
	position, _ := node.GetPosition()

	if style.AutoSize {
		triggerEvent(node, OnSizeChange, origen)
	}

	if position.Type.Center > None && position.Type.Center <= PositionXY {
		triggerEvent(node, OnMove, origen)
	}

	if !style.AutoSize && position.Type.Center == None {
		return
	}

	if deep {
		childNodes, _ := node.GetChildren()
		for _, childNode := range childNodes {
			autoSizeChangeTrigger(childNode, origen, deep)
		}
	}
}
